<!DOCTYPE html>
            
<HTML>
<HEAD>
<meta name="booktitle" content="Developing Applications With Objective Caml" >
 <meta charset="ISO-8859-1"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<META name="GENERATOR" content="hevea 1.05-7 of 2000-02-24">
<META NAME="Author" CONTENT="Christian.Queinnec@lip6.fr">
<LINK rel=stylesheet type="text/css" href="videoc-ocda.css">
<script language="JavaScript" src="videoc.js"><!--
//--></script>
<TITLE>
 Exercises
</TITLE>
</HEAD>
<BODY class="regularBody">
<A HREF="book-ora188.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora190.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2> Exercises</H2>The suggested exercises allow you to try different types of 
distributed applications. The first offers a new network 
service for setting the time on client machines.
The second exercise shows how to use resources on 
different machines to distribute a calculation.<BR>
<BR>
<A NAME="toc287"></A>
<H3> Service: Clock</H3>This exercise consists of implementing a ``clock'' service that 
gives the time to any client. The idea is to have a reference 
machine to set the time for different machines on a network.<BR>
<BR>
<OL type=1>
<LI>
 Define a <A id="a310__1_APPEND/PDcor.ml.tex" href="javascript: void showMessage('1_APPEND/PDcor.ml.tex')" class="mousable"><SPAN style=""><!-- 1,APPEND/PDcor.ml.tex,clock-protocol -->protocol</SPAN></A> for  
transmitting a date containing the day, month, hour, minute, and
second. 
<!-- POPUP DEFINITION -->
<layer id="l__1_APPEND/PDcor.ml.tex" class="hint" visibility="hide" style="visibility:hidden; position:absolute" width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","1_APPEND/PDcor.ml.tex","");
// --></script><span style="">
 

<PRE><BR># <B>type</B><CODE> </CODE>horloge<CODE> </CODE><CODE>=</CODE><CODE> </CODE>{<CODE> </CODE>jour<CODE>:</CODE>int;<CODE> </CODE>mois<CODE>:</CODE>int;<CODE> </CODE>heure<CODE>:</CODE>int;<CODE> </CODE>minute<CODE>:</CODE>int;<CODE> </CODE>seconde<CODE>:</CODE>int<CODE> </CODE>}<CODE> </CODE>;;<BR><CODE>type horloge =</CODE><BR><CODE>  { jour: int;</CODE><BR><CODE>    mois: int;</CODE><BR><CODE>    heure: int;</CODE><BR><CODE>    minute: int;</CODE><BR><CODE>    seconde: int }</CODE><BR># <B>let</B><CODE> </CODE>encode<CODE> </CODE>date<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>str<CODE> </CODE><CODE>=</CODE><CODE> </CODE>String.create<CODE> </CODE><CODE>5</CODE><CODE> </CODE><B>in</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>str<CODE>.[</CODE><CODE>0</CODE><CODE>]</CODE><CODE> </CODE><CODE>&lt;-</CODE><CODE> </CODE>char_of_int<CODE> </CODE>date<CODE>.</CODE>jour<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>str<CODE>.[</CODE><CODE>1</CODE><CODE>]</CODE><CODE> </CODE><CODE>&lt;-</CODE><CODE> </CODE>char_of_int<CODE> </CODE>date<CODE>.</CODE>mois<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>str<CODE>.[</CODE><CODE>2</CODE><CODE>]</CODE><CODE> </CODE><CODE>&lt;-</CODE><CODE> </CODE>char_of_int<CODE> </CODE>date<CODE>.</CODE>heure<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>str<CODE>.[</CODE><CODE>3</CODE><CODE>]</CODE><CODE> </CODE><CODE>&lt;-</CODE><CODE> </CODE>char_of_int<CODE> </CODE>date<CODE>.</CODE>minute<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>str<CODE>.[</CODE><CODE>4</CODE><CODE>]</CODE><CODE> </CODE><CODE>&lt;-</CODE><CODE> </CODE>char_of_int<CODE> </CODE>date<CODE>.</CODE>seconde<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>str<CODE> </CODE>;;<BR><CODE>val encode : horloge -&gt; string = &lt;fun&gt;</CODE><BR># <B>let</B><CODE> </CODE>decode<CODE> </CODE>str<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>jour<CODE> </CODE><CODE>=</CODE><CODE> </CODE>int_of_char<CODE> </CODE>str<CODE>.[</CODE><CODE>0</CODE><CODE>]</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>mois<CODE> </CODE><CODE>=</CODE><CODE> </CODE>int_of_char<CODE> </CODE>str<CODE>.[</CODE><CODE>1</CODE><CODE>]</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>heure<CODE> </CODE><CODE>=</CODE><CODE> </CODE>int_of_char<CODE> </CODE>str<CODE>.[</CODE><CODE>2</CODE><CODE>]</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>minute<CODE> </CODE><CODE>=</CODE><CODE> </CODE>int_of_char<CODE> </CODE>str<CODE>.[</CODE><CODE>3</CODE><CODE>]</CODE><CODE> </CODE>;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>seconde<CODE> </CODE><CODE>=</CODE><CODE> </CODE>int_of_char<CODE> </CODE>str<CODE>.[</CODE><CODE>4</CODE><CODE>]</CODE><CODE> </CODE>}<CODE> </CODE>;;<BR><CODE>val decode : string -&gt; horloge = &lt;fun&gt;</CODE><BR>

</PRE>

</span><script language="JavaScript"><!--
  closePopUp("1_APPEND/PDcor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<script language="JavaScript"><!--
  initializePreviousHints();
// --></script><BR>
<BR>

<LI> Write the <A id="a311__2_APPEND/PDcor.ml.tex" href="javascript: void showMessage('2_APPEND/PDcor.ml.tex')" class="mousable"><SPAN style=""><!-- 2,APPEND/PDcor.ml.tex,clock-fonction -->function</SPAN></A> or the class for  
the service reusing one of the generic servers presented in the Chapter.
The service sends date information over each accepted connection,
then closes the socket. 
<!-- POPUP DEFINITION -->
<layer id="l__2_APPEND/PDcor.ml.tex" class="hint" visibility="hide" style="visibility:hidden; position:absolute" width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","2_APPEND/PDcor.ml.tex","");
// --></script><span style="">
 Nous utilisons la fonction <TT>main_serveur</TT>(<A HREF="book-ora187.html#mainserveur">20</A>) :


<PRE><BR># main_serveur<CODE> </CODE>;;<BR><CODE>- : (in_channel -&gt; out_channel -&gt; 'a) -&gt; unit = &lt;fun&gt;</CODE><BR><BR># <B>let</B><CODE> </CODE>horloge_service<CODE> </CODE>ic<CODE> </CODE>oc<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>try</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>date<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Unix.localtime<CODE> </CODE><TT>(</TT>Unix.time<CODE> </CODE>()<TT>)</TT><CODE> </CODE><B>in</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>date_horloge<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>jour<CODE> </CODE><CODE>=</CODE><CODE> </CODE>date<CODE>.</CODE>Unix.tm_mday<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>mois<CODE> </CODE><CODE>=</CODE><CODE> </CODE>date<CODE>.</CODE>Unix.tm_mon<CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE>;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>heure<CODE> </CODE><CODE>=</CODE><CODE> </CODE>date<CODE>.</CODE>Unix.tm_hour<CODE> </CODE>;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>minute<CODE> </CODE><CODE>=</CODE><CODE> </CODE>date<CODE>.</CODE>Unix.tm_min<CODE> </CODE>;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>seconde<CODE> </CODE><CODE>=</CODE><CODE> </CODE>date<CODE>.</CODE>Unix.tm_sec<CODE> </CODE><CODE> </CODE>}<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>output_string<CODE> </CODE>oc<CODE> </CODE><TT>(</TT>encode<CODE> </CODE>date_horloge<TT>)</TT><CODE> </CODE>;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>flush<CODE> </CODE>oc<CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>with</B><CODE> </CODE>exn<CODE> </CODE>-&gt;<CODE> </CODE>print_endline<CODE> </CODE><CODE>"Fin du traitement"</CODE>;<CODE> </CODE>flush<CODE> </CODE>stdout<CODE> </CODE><BR><CODE> </CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE>main_horloge<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE>main_serveur<CODE> </CODE>horloge_service<CODE> </CODE>;;<BR><CODE>val horloge_service : 'a -&gt; out_channel -&gt; unit = &lt;fun&gt;</CODE><BR><CODE>val main_horloge : unit -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>

</span><script language="JavaScript"><!--
  closePopUp("2_APPEND/PDcor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<script language="JavaScript"><!--
  initializePreviousHints();
// --></script><BR>
<BR>

<LI> Write the <A id="a312__3_APPEND/PDcor.ml.tex" href="javascript: void showMessage('3_APPEND/PDcor.ml.tex')" class="mousable"><SPAN style=""><!-- 3,APPEND/PDcor.ml.tex,clock-client -->client</SPAN></A> , which sets the 
clock every hour.
<!-- POPUP DEFINITION -->
<layer id="l__3_APPEND/PDcor.ml.tex" class="hint" visibility="hide" style="visibility:hidden; position:absolute" width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","3_APPEND/PDcor.ml.tex","");
// --></script><span style="">
 Nous utilisons la fonction <TT>main_client</TT><A HREF="book-ora187.html#mainclient">20</A> :


<PRE><BR># main_client<CODE> </CODE>;;<BR><CODE>- : (in_channel -&gt; out_channel -&gt; 'a) -&gt; unit = &lt;fun&gt;</CODE><BR><BR># <B>let</B><CODE> </CODE>client_horloge<CODE> </CODE>ic<CODE> </CODE>oc<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>date<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE>{<CODE> </CODE>jour<CODE>=</CODE><CODE>0</CODE>;<CODE> </CODE>mois<CODE>=</CODE><CODE>0</CODE>;<CODE> </CODE>heure<CODE>=</CODE><CODE>0</CODE>;<CODE> </CODE>minute<CODE>=</CODE><CODE>0</CODE>;<CODE> </CODE>seconde<CODE>=</CODE><CODE>0</CODE><CODE> </CODE>}<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>try</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>while</B><CODE> </CODE><B>true</B><CODE> </CODE><B>do</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>buffer<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>"xxxxx"</CODE><CODE> </CODE><B>in</B><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>ignore<CODE> </CODE><TT>(</TT>input<CODE> </CODE>ic<CODE> </CODE>buffer<CODE> </CODE><CODE>0</CODE><CODE> </CODE><CODE>5</CODE><TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>date<CODE> </CODE><CODE>:=</CODE><CODE> </CODE>decode<CODE> </CODE>buffer<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>print_endline<CODE> </CODE><CODE>"BIP"</CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>flush<CODE> </CODE>stdout<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Unix.sleep<CODE> </CODE><CODE>3</CODE><CODE>6</CODE><CODE>0</CODE><CODE>0</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>with</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>exn<CODE> </CODE>-&gt;<CODE> </CODE>shutdown_connection<CODE> </CODE>ic<CODE> </CODE>;<CODE> </CODE>raise<CODE> </CODE>exn<CODE> </CODE><CODE> </CODE>;;<BR><CODE>val client_horloge : in_channel -&gt; 'a -&gt; unit = &lt;fun&gt;</CODE><BR><BR># <B>let</B><CODE> </CODE>main_horloge<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE>main_client<CODE> </CODE>client_horloge<CODE> </CODE>;;<BR><CODE>val main_horloge : unit -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>

</span><script language="JavaScript"><!--
  closePopUp("3_APPEND/PDcor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<script language="JavaScript"><!--
  initializePreviousHints();
// --></script><BR>
<BR>

<LI> 
Keep <A id="a313__4_APPEND/PDcor.ml.tex" href="javascript: void showMessage('4_APPEND/PDcor.ml.tex')" class="mousable"><SPAN style=""><!-- 4,APPEND/PDcor.ml.tex,clock-account -->track</SPAN></A> of time differences when  
requests are sent.
<!-- POPUP DEFINITION -->
<layer id="l__4_APPEND/PDcor.ml.tex" class="hint" visibility="hide" style="visibility:hidden; position:absolute" width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","4_APPEND/PDcor.ml.tex","");
// --></script><span style="">
 On peut mesurer le temps �coul� entre la demande de connexion et
la r�ception de la r�ponse. On suppose que ce d�lai est le
double de celui mis par la r�ponse et on corrige le r�sultat en cons�quence.
</span><script language="JavaScript"><!--
  closePopUp("4_APPEND/PDcor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<script language="JavaScript"><!--
  initializePreviousHints();
// --></script></OL><A NAME="toc288"></A>
<H3> A Network Coffee Machine</H3>We can build a little service that simulates a beverage 
vending machine. A summary description of the protocol between
the client and service is as follows:
<UL>
<LI>
 when it makes a connection, the client receives a 
list of available drinks;

<LI> it then sends to the server its beverage choice;

<LI> the server returns the price of the beverage;

<LI> the client sends the requested price, or some other sum;

<LI> the server responds with the name of the chosen beverage 
and shows the change tendered. 
</UL>
The server may also respond with an error message if it has not
understood a request, does not have enough change, etc. A client 
request always contains just one piece of information.<BR>
<BR>
The exchanges between client and server are in the form of 
strings of characters. The different components of a message are 
separated by two periods and all strings end in <CODE>:$\n</CODE>.<BR>
<BR>
The service function communicates with the coffee machine by using a 
file to pass commands and a hash table for 
recovering drinks and change.<BR>
<BR>
This exercise will make use of sockets, lightweight processes with 
a little concurrency, and objects.<BR>
<BR>
<OL type=1>
<LI>
 Rewrite the function <TT><A id="a314__5_APPEND/PDcor.ml.tex" href="javascript: void showMessage('5_APPEND/PDcor.ml.tex')" class="mousable"><SPAN style=""><!-- 5,APPEND/PDcor.ml.tex,server -->establish_server</SPAN></A></TT> 
using the primitives in <TT>ThreadUnix</TT>.
<!-- POPUP DEFINITION -->
<layer id="l__5_APPEND/PDcor.ml.tex" class="hint" visibility="hide" style="visibility:hidden; position:absolute" width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","5_APPEND/PDcor.ml.tex","");
// --></script><span style="">
 On reprend les fonctions <TT>hostaddr</TT> et <TT>my_inet_addr</TT>
de ce chapitre. 


<PRE><BR># <CODE>val hostaddr : string -&gt; Unix.inet_addr = &lt;fun&gt;</CODE><BR><CODE>val my_inet_addr : unit -&gt; Unix.inet_addr = &lt;fun&gt;</CODE><BR><BR><CODE> </CODE><B>let</B><CODE> </CODE>establish_server<CODE> </CODE>f<CODE> </CODE>saddr<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>sock<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ThreadUnix.socket<CODE> </CODE>Unix<CODE>.</CODE>PF_INET<CODE> </CODE>Unix<CODE>.</CODE>SOCK_STREAM<CODE> </CODE><CODE>0</CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Unix.bind<CODE> </CODE>sock<CODE> </CODE>saddr;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Unix.listen<CODE> </CODE>sock<CODE> </CODE><CODE>5</CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>while</B><CODE> </CODE><B>true</B><CODE> </CODE><B>do</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><TT>(</TT>s<CODE>,_</CODE><TT>)</TT><CODE> </CODE><CODE>=</CODE><CODE> </CODE>ThreadUnix.accept<CODE> </CODE>sock<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>ic<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Unix.in_channel_of_descr<CODE> </CODE>s<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>and</B><CODE> </CODE>oc<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Unix.out_channel_of_descr<CODE> </CODE>s<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>ignore<CODE> </CODE><TT>(</TT>Thread.create<CODE> </CODE><TT>(</TT>f<CODE> </CODE>ic<TT>)</TT><CODE> </CODE>oc<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B>;;<BR><CODE>val establish_server :</CODE><BR><CODE>  (in_channel -&gt; out_channel -&gt; 'a) -&gt; Unix.sockaddr -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>

</span><script language="JavaScript"><!--
  closePopUp("5_APPEND/PDcor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<script language="JavaScript"><!--
  initializePreviousHints();
// --></script><BR>
<BR>

<LI> Write two functions, <TT><A id="a315__6_APPEND/PDcor.ml.tex" href="javascript: void showMessage('6_APPEND/PDcor.ml.tex')" class="mousable"><SPAN style=""><!-- 6,APPEND/PDcor.ml.tex,getreq -->get_request</SPAN></A></TT> 
and <TT><A id="a316__7_APPEND/PDcor.ml.tex" href="javascript: void showMessage('7_APPEND/PDcor.ml.tex')" class="mousable"><SPAN style=""><!-- 7,APPEND/PDcor.ml.tex,sendans -->send_answer</SPAN></A></TT>. The first function 
reads and encodes a request and the second formats and sends 
a response beginning with a list of strings of characters.
<!-- POPUP DEFINITION -->
<layer id="l__6_APPEND/PDcor.ml.tex" class="hint" visibility="hide" style="visibility:hidden; position:absolute" width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","6_APPEND/PDcor.ml.tex","");
// --></script><span style="">
 

<PRE><BR># <B>let</B><CODE> </CODE>read<CODE> </CODE>fd<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>buf<CODE> </CODE><CODE>=</CODE><CODE> </CODE>String.create<CODE> </CODE><CODE>1</CODE><CODE>0</CODE><CODE>2</CODE><CODE>4</CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ThreadUnix.read<CODE> </CODE>fd<CODE> </CODE>buf<CODE> </CODE><CODE>0</CODE><CODE> </CODE><CODE>1</CODE><CODE>0</CODE><CODE>2</CODE><CODE>4</CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><CODE> </CODE>String.sub<CODE> </CODE>buf<CODE> </CODE><CODE>0</CODE><CODE> </CODE>n<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>s<CODE> </CODE>;;<BR><CODE>val read : Unix.file_descr -&gt; string = &lt;fun&gt;</CODE><BR><BR># <B>let</B><CODE> </CODE>get_request<CODE> </CODE>fd<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><CODE> </CODE>read<CODE> </CODE>fd<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>Str.split<CODE> </CODE><TT>(</TT>Str.regexp<CODE> </CODE><CODE>"[:]"</CODE><TT>)</TT><CODE> </CODE><TT>(</TT>String.sub<CODE> </CODE>s<CODE> </CODE><CODE>0</CODE><CODE> </CODE><TT>(</TT>String.index<CODE> </CODE>s<CODE> </CODE><CODE>'$'</CODE><TT>)</TT><TT>)</TT><CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>[</CODE>s1<CODE>]</CODE><CODE> </CODE>-&gt;<CODE> </CODE>s1<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE>failwith<CODE> </CODE><CODE>"BadRequestFormat"</CODE><CODE> </CODE>;;<BR><CODE>val get_request : Unix.file_descr -&gt; string = &lt;fun&gt;</CODE><BR>

</PRE>

</span><script language="JavaScript"><!--
  closePopUp("6_APPEND/PDcor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<!-- POPUP DEFINITION -->
<layer id="l__7_APPEND/PDcor.ml.tex" class="hint" visibility="hide" style="visibility:hidden; position:absolute" width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","7_APPEND/PDcor.ml.tex","");
// --></script><span style="">
 On red�finit des fonctions d'entr�es-sorties utilisant celles de
<TT>Threadunix</TT> puis on les utilise pour <TT>get_request</TT> et
<TT>send_answer</TT>. Comme elle revient souvent, on d�finit
�galement une fonction <TT>send_cancel</TT> qui envoie un message
d'erreur. 


<PRE><BR># <B>let</B><CODE> </CODE>write<CODE> </CODE>fd<CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>leng<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT>String.length<CODE> </CODE>s<TT>)</TT><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ThreadUnix.write<CODE> </CODE>fd<CODE> </CODE>s<CODE> </CODE><CODE>0</CODE><CODE> </CODE>leng<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>n<CODE>&lt;</CODE>leng<CODE> </CODE><B>then</B><CODE> </CODE>failwith<CODE> </CODE><CODE>"I/O error"</CODE><CODE> </CODE>;;<BR><CODE>val write : Unix.file_descr -&gt; string -&gt; unit = &lt;fun&gt;</CODE><BR><BR># <B>let</B><CODE> </CODE>send_answer<CODE> </CODE>fd<CODE> </CODE>ss<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>mk_answer<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>function</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>[]<CODE> </CODE>-&gt;<CODE> </CODE><CODE>":$\n"</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>[</CODE>s<CODE>]</CODE><CODE> </CODE>-&gt;<CODE> </CODE>s<CODE> </CODE><CODE>^</CODE><CODE> </CODE><CODE>":$\n"</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>s::ss<CODE> </CODE>-&gt;<CODE> </CODE>s<CODE> </CODE><CODE>^</CODE><CODE> </CODE><CODE>":"</CODE><CODE> </CODE><CODE>^</CODE><CODE> </CODE><TT>(</TT>mk_answer<CODE> </CODE>ss<TT>)</TT><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>write<CODE> </CODE>fd<CODE> </CODE><TT>(</TT>mk_answer<CODE> </CODE>ss<TT>)</TT><CODE> </CODE>;;<BR><CODE>val send_answer : Unix.file_descr -&gt; string list -&gt; unit = &lt;fun&gt;</CODE><BR><BR># <B>let</B><CODE> </CODE>send_cancel<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>let</B><CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>"cancel:$\n"</CODE><CODE> </CODE><B>in</B><CODE> </CODE><B>function</B><CODE> </CODE>fd<CODE> </CODE>-&gt;<CODE> </CODE>write<CODE> </CODE>fd<CODE> </CODE>s<CODE> </CODE>;;<BR><CODE>val send_cancel : Unix.file_descr -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>

</span><script language="JavaScript"><!--
  closePopUp("7_APPEND/PDcor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<script language="JavaScript"><!--
  initializePreviousHints();
// --></script><BR>
<BR>

<LI> Write a class <TT><A id="a317__8_APPEND/PDcor.ml.tex" href="javascript: void showMessage('8_APPEND/PDcor.ml.tex')" class="mousable"><SPAN style=""><!-- 8,APPEND/PDcor.ml.tex,cmdfifo -->cmd_fifo</SPAN></A></TT> 
to manage pending commands. Each new command is assigned 
a unique number. For this purpose, implement a class 
<TT><A id="a318__9_APPEND/PDcor.ml.tex" href="javascript: void showMessage('9_APPEND/PDcor.ml.tex')" class="mousable"><SPAN style=""><!-- 9,APPEND/PDcor.ml.tex,numcmdgen -->num_cmd_gen</SPAN></A></TT>. 
<!-- POPUP DEFINITION -->
<layer id="l__8_APPEND/PDcor.ml.tex" class="hint" visibility="hide" style="visibility:hidden; position:absolute" width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","8_APPEND/PDcor.ml.tex","");
// --></script><span style="">
 

<PRE><BR># <B>class</B><CODE> </CODE>cmd_fifo<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>object</B><TT>(</TT>self<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>new</B><CODE> </CODE>num_cmd_gen<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>f<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT>Queue.create<CODE> </CODE>()<CODE>:</CODE><CODE> </CODE><TT>(</TT>int<CODE>*</CODE>int<CODE>*</CODE>int<TT>)</TT><CODE> </CODE>Queue.t<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>m<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Mutex.create<CODE> </CODE>()<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>c<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Condition.create<CODE> </CODE>()<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>method</B><CODE> </CODE>add<CODE> </CODE>num_drink<CODE> </CODE>paid<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>num_cmd<CODE> </CODE><CODE>=</CODE><CODE> </CODE>n#get()<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Mutex.lock<CODE> </CODE>m<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Queue.add<CODE> </CODE><TT>(</TT>num_cmd<CODE>,</CODE><CODE> </CODE>num_drink<CODE>,</CODE><CODE> </CODE>paid<TT>)</TT><CODE> </CODE>f<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Mutex.unlock<CODE> </CODE>m<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Condition.signal<CODE> </CODE>c<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>num_cmd<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>method</B><CODE> </CODE>wait<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Mutex.lock<CODE> </CODE>m<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Condition.wait<CODE> </CODE>c<CODE> </CODE>m<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>cmd<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Queue.take<CODE> </CODE>f<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Mutex.unlock<CODE> </CODE>m<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>cmd<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>end</B><CODE> </CODE>;;<BR><CODE>class cmd_fifo :</CODE><BR><CODE>  object</CODE><BR><CODE>    val c : Condition.t</CODE><BR><CODE>    val f : (int * int * int) Queue.t</CODE><BR><CODE>    val m : Mutex.t</CODE><BR><CODE>    val n : num_cmd_gen</CODE><BR><CODE>    method add : int -&gt; int -&gt; int</CODE><BR><CODE>    method wait : unit -&gt; int * int * int</CODE><BR><CODE>  end</CODE><BR>

</PRE>

</span><script language="JavaScript"><!--
  closePopUp("8_APPEND/PDcor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<!-- POPUP DEFINITION -->
<layer id="l__9_APPEND/PDcor.ml.tex" class="hint" visibility="hide" style="visibility:hidden; position:absolute" width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","9_APPEND/PDcor.ml.tex","");
// --></script><span style="">
 

<PRE><BR># <B>class</B><CODE> </CODE>num_cmd_gen<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>object</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE><B>mutable</B><CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>0</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>m<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Mutex.create<CODE> </CODE>()<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>method</B><CODE> </CODE>get()<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Mutex.lock<CODE> </CODE>m<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>x<CODE> </CODE><CODE>&lt;-</CODE><CODE> </CODE>x<CODE>+</CODE><CODE>1</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>r<CODE> </CODE><CODE>=</CODE><CODE> </CODE>x<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Mutex.unlock<CODE> </CODE>m<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>r<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>end</B><CODE> </CODE>;;<BR><CODE>class num_cmd_gen :</CODE><BR><CODE>  object val m : Mutex.t val mutable x : int method get : unit -&gt; int end</CODE><BR>

</PRE>

</span><script language="JavaScript"><!--
  closePopUp("9_APPEND/PDcor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<script language="JavaScript"><!--
  initializePreviousHints();
// --></script><BR>
<BR>

<LI> Write a class <TT><A id="a319__10_APPEND/PDcor.ml.tex" href="javascript: void showMessage('10_APPEND/PDcor.ml.tex')" class="mousable"><SPAN style=""><!-- 10,APPEND/PDcor.ml.tex,readytable -->ready_table</SPAN></A></TT> 
for stocking the machine with drinks.
<!-- POPUP DEFINITION -->
<layer id="l__10_APPEND/PDcor.ml.tex" class="hint" visibility="hide" style="visibility:hidden; position:absolute" width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","10_APPEND/PDcor.ml.tex","");
// --></script><span style="">
 

<PRE><BR># <B>class</B><CODE> </CODE>ready_table<CODE> </CODE>size<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>object</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>t<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT>Hashtbl.create<CODE> </CODE>size<CODE> </CODE><CODE>:</CODE><CODE> </CODE><TT>(</TT>int<CODE>,</CODE><CODE> </CODE><TT>(</TT>string<CODE> </CODE><CODE>*</CODE><CODE> </CODE>int<TT>)</TT><TT>)</TT><CODE> </CODE>Hashtbl.t<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>m<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Mutex.create<CODE> </CODE>()<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>c<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Condition.create<CODE> </CODE>()<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>method</B><CODE> </CODE>add<CODE> </CODE>num_cmd<CODE> </CODE>num_drink<CODE> </CODE>change<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Mutex.lock<CODE> </CODE>m<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Hashtbl.add<CODE> </CODE>t<CODE> </CODE>num_cmd<CODE> </CODE><TT>(</TT>num_drink<CODE>,</CODE><CODE> </CODE>change<TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Mutex.unlock<CODE> </CODE>m<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Condition.broadcast<CODE> </CODE>c<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>method</B><CODE> </CODE>wait<CODE> </CODE>num_cmd<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Mutex.lock<CODE> </CODE>m;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>while</B><CODE> </CODE>not<TT>(</TT>Hashtbl.mem<CODE> </CODE>t<CODE> </CODE>num_cmd<TT>)</TT><CODE> </CODE><B>do</B><CODE> </CODE>Condition.wait<CODE> </CODE>c<CODE> </CODE>m<CODE> </CODE><B>done</B><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>cmd<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Hashtbl.find<CODE> </CODE>t<CODE> </CODE>num_cmd<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Hashtbl.remove<CODE> </CODE>t<CODE> </CODE>num_cmd<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Mutex.unlock<CODE> </CODE>m<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>cmd<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>end</B><CODE> </CODE>;;<BR><CODE>class ready_table :</CODE><BR><CODE>  int -&gt;</CODE><BR><CODE>  object</CODE><BR><CODE>    val c : Condition.t</CODE><BR><CODE>    val m : Mutex.t</CODE><BR><CODE>    val t : (int, string * int) Hashtbl.t</CODE><BR><CODE>    method add : int -&gt; string -&gt; int -&gt; unit</CODE><BR><CODE>    method wait : int -&gt; string * int</CODE><BR><CODE>  end</CODE><BR>

</PRE>

</span><script language="JavaScript"><!--
  closePopUp("10_APPEND/PDcor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<script language="JavaScript"><!--
  initializePreviousHints();
// --></script><BR>
<BR>

<LI> Write the class <TT><A id="a320__11_APPEND/PDcor.ml.tex" href="javascript: void showMessage('11_APPEND/PDcor.ml.tex')" class="mousable"><SPAN style=""><!-- 11,APPEND/PDcor.ml.tex,machine -->machine</SPAN></A></TT> that  
models the coffee machine. The class contains a method 
<TT>run</TT> that loops through the sequence: wait for a command,
then execute it, as long as there remain drinks available. 
Define a type <I><A id="a321__12_APPEND/PDcor.ml.tex" href="javascript: void showMessage('12_APPEND/PDcor.ml.tex')" class="mousable"><SPAN style=""><!-- 12,APPEND/PDcor.ml.tex,drinkdescr -->drink_descr</SPAN></A></I> indicating, 
for each drink: its name, the quantity in stock, the quantity 
that will remain after satisying pending commands, and its price.
We can use an auxiliary function <TT><A id="a322__13_APPEND/PDcor.ml.tex" href="javascript: void showMessage('13_APPEND/PDcor.ml.tex')" class="mousable"><SPAN style=""><!-- 13,APPEND/PDcor.ml.tex,arrayindex -->array_index</SPAN></A></TT> 
which returns the index of the first element in a table satisfying 
a criterion passed as a parameter.
<!-- POPUP DEFINITION -->
<layer id="l__11_APPEND/PDcor.ml.tex" class="hint" visibility="hide" style="visibility:hidden; position:absolute" width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","11_APPEND/PDcor.ml.tex","");
// --></script><span style="">
 

<PRE><BR># <B>class</B><CODE> </CODE>machine<CODE> </CODE><TT>(</TT>f_cmd0<CODE>:</CODE>cmd_fifo<TT>)</TT><CODE> </CODE><TT>(</TT>t_ready0<CODE>:</CODE>ready_table<TT>)</TT><CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>object</B><TT>(</TT>self<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>f_cmd<CODE> </CODE><CODE>=</CODE><CODE> </CODE>f_cmd0<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>t_ready<CODE> </CODE><CODE>=</CODE><CODE> </CODE>t_ready0<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE><B>mutable</B><CODE> </CODE>nb_available_drinks<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>0</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>drinks_table<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>[|</CODE><CODE> </CODE>{<CODE> </CODE>name<CODE>=</CODE><CODE>"cafe"</CODE>;<CODE> </CODE>real_stock<CODE>=</CODE><CODE>1</CODE><CODE>0</CODE>;<CODE> </CODE>virtual_stock<CODE>=</CODE><CODE>1</CODE><CODE>0</CODE>;<CODE> </CODE>price<CODE>=</CODE><CODE>3</CODE><CODE>0</CODE><CODE>0</CODE><CODE> </CODE>};<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>name<CODE>=</CODE><CODE>"the"</CODE>;<CODE> </CODE>real_stock<CODE>=</CODE><CODE>5</CODE>;<CODE> </CODE>virtual_stock<CODE>=</CODE><CODE>5</CODE>;<CODE> </CODE>price<CODE>=</CODE><CODE>2</CODE><CODE>5</CODE><CODE>0</CODE><CODE> </CODE>};<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>name<CODE>=</CODE><CODE>"chocolat"</CODE>;<CODE> </CODE>real_stock<CODE>=</CODE><CODE>1</CODE><CODE>0</CODE>;<CODE> </CODE>virtual_stock<CODE>=</CODE><CODE>1</CODE><CODE>0</CODE>;<CODE> </CODE>price<CODE>=</CODE><CODE>2</CODE><CODE>5</CODE><CODE>0</CODE><CODE> </CODE>}<CODE> </CODE><CODE>|]</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE><B>mutable</B><CODE> </CODE>cash<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>0</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>m<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Mutex.create()<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>initializer</B><CODE> </CODE><CODE> </CODE>nb_available_drinks<CODE> </CODE><CODE>&lt;-</CODE><CODE> </CODE>Array.length<CODE> </CODE>drinks_table<BR><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>method</B><CODE> </CODE>get_drink_price<CODE> </CODE>i<CODE> </CODE><CODE>=</CODE><CODE> </CODE>drinks_table<CODE>.</CODE><TT>(</TT>i<TT>)</TT><CODE>.</CODE>price<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>method</B><CODE> </CODE>get_drink_index<CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><CODE> </CODE>array_index<CODE> </CODE>drinks_table<CODE> </CODE><TT>(</TT><B>fun</B><CODE> </CODE>d<CODE> </CODE>-&gt;<CODE> </CODE>d<CODE>.</CODE>name<CODE>=</CODE>s<TT>)</TT><BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>method</B><CODE> </CODE>get_menu<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>f<CODE> </CODE>d<CODE> </CODE>ns<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>if</B><CODE> </CODE>d<CODE>.</CODE>real_stock<CODE> </CODE><CODE>&gt;</CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE><B>then</B><CODE> </CODE>d<CODE>.</CODE>name::ns<CODE> </CODE><B>else</B><CODE> </CODE>ns<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Array.fold_right<CODE> </CODE>f<CODE> </CODE>drinks_table<CODE> </CODE>[]<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>method</B><CODE> </CODE>cancel_cmd<CODE> </CODE>num_drink<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>drink<CODE> </CODE><CODE>=</CODE><CODE> </CODE>drinks_table<CODE>.</CODE><TT>(</TT>num_drink<TT>)</TT><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>drink<CODE>.</CODE>virtual_stock<CODE> </CODE><CODE>&lt;-</CODE><CODE> </CODE>drink<CODE>.</CODE>virtual_stock<CODE>+</CODE><CODE>1</CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>method</B><CODE> </CODE>set_cmd<CODE> </CODE>num_drink<CODE> </CODE>paid<CODE> </CODE><CODE>=</CODE><CODE> </CODE>f_cmd#add<CODE> </CODE>num_drink<CODE> </CODE>paid<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>method</B><CODE> </CODE>wait_cmd<CODE> </CODE>num_cmd<CODE> </CODE><CODE>=</CODE><CODE> </CODE>t_ready#wait<CODE> </CODE>num_cmd<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>method</B><CODE> </CODE>deliver_drink<CODE> </CODE>num_drink<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>drink<CODE> </CODE><CODE>=</CODE><CODE> </CODE>drinks_table<CODE>.</CODE><TT>(</TT>num_drink<TT>)</TT><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>drink<CODE>.</CODE>real_stock<CODE> </CODE><CODE>&lt;-</CODE><CODE> </CODE>drink<CODE>.</CODE>real_stock<CODE>-</CODE><CODE>1</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>drink<CODE>.</CODE>real_stock<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE><B>then</B><CODE> </CODE>nb_available_drinks<CODE> </CODE><CODE>&lt;-</CODE><CODE> </CODE>nb_available_drinks<CODE>-</CODE><CODE>1</CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>method</B><CODE> </CODE>run()<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>while</B><CODE> </CODE>nb_available_drinks<CODE>&gt;</CODE><CODE>0</CODE><CODE> </CODE><B>do</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><TT>(</TT>num_cmd<CODE>,</CODE><CODE> </CODE>num_drink<CODE>,</CODE><CODE> </CODE>amount<TT>)</TT><CODE> </CODE><CODE>=</CODE><CODE> </CODE>f_cmd#wait<CODE> </CODE>()<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>drink<CODE> </CODE><CODE>=</CODE><CODE> </CODE>drinks_table<CODE>.</CODE><TT>(</TT>num_drink<TT>)</TT><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>change<CODE> </CODE><CODE>=</CODE><CODE> </CODE>amount<CODE> </CODE><CODE>-</CODE><CODE> </CODE>drink<CODE>.</CODE>price<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Mutex.lock<CODE> </CODE>m<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE><TT>(</TT>drink<CODE>.</CODE>virtual_stock<CODE> </CODE><CODE>&gt;</CODE><CODE> </CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE><CODE>&amp;</CODE><CODE> </CODE><TT>(</TT>cash<CODE> </CODE><CODE>&gt;=</CODE><CODE> </CODE>change<TT>)</TT><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>then</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>begin</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>drink<CODE>.</CODE>virtual_stock<CODE> </CODE><CODE>&lt;-</CODE><CODE> </CODE>drink<CODE>.</CODE>virtual_stock<CODE>-</CODE><CODE>1</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>cash<CODE> </CODE><CODE>&lt;-</CODE><CODE> </CODE>cash<CODE> </CODE><CODE>+</CODE><CODE> </CODE>drink<CODE>.</CODE>price<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>t_ready#add<CODE> </CODE>num_cmd<CODE> </CODE>drink<CODE>.</CODE>name<CODE> </CODE>change<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>end</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE>t_ready#add<CODE> </CODE>num_cmd<CODE> </CODE><CODE>"cancel"</CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Mutex.unlock<CODE> </CODE>m<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>end</B><CODE> </CODE>;;<BR><CODE>class machine :</CODE><BR><CODE>  cmd_fifo -&gt;</CODE><BR><CODE>  ready_table -&gt;</CODE><BR><CODE>  object</CODE><BR><CODE>    val mutable cash : int</CODE><BR><CODE>    val drinks_table : drink_descr array</CODE><BR><CODE>    val f_cmd : cmd_fifo</CODE><BR><CODE>    val m : Mutex.t</CODE><BR><CODE>    val mutable nb_available_drinks : int</CODE><BR><CODE>    val t_ready : ready_table</CODE><BR><CODE>    method cancel_cmd : int -&gt; unit</CODE><BR><CODE>    method deliver_drink : int -&gt; unit</CODE><BR><CODE>    method get_drink_index : string -&gt; int</CODE><BR><CODE>    method get_drink_price : int -&gt; int</CODE><BR><CODE>    method get_menu : unit -&gt; string list</CODE><BR><CODE>    method run : unit -&gt; unit</CODE><BR><CODE>    method set_cmd : int -&gt; int -&gt; int</CODE><BR><CODE>    method wait_cmd : int -&gt; string * int</CODE><BR><CODE>  end</CODE><BR>

</PRE>

</span><script language="JavaScript"><!--
  closePopUp("11_APPEND/PDcor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<!-- POPUP DEFINITION -->
<layer id="l__12_APPEND/PDcor.ml.tex" class="hint" visibility="hide" style="visibility:hidden; position:absolute" width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","12_APPEND/PDcor.ml.tex","");
// --></script><span style="">
 

<PRE><BR># <B>type</B><CODE> </CODE>drink_descr<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>{<CODE> </CODE>name<CODE> </CODE><CODE>:</CODE><CODE> </CODE>string;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>mutable</B><CODE> </CODE>real_stock<CODE> </CODE><CODE>:</CODE><CODE> </CODE>int;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>mutable</B><CODE> </CODE>virtual_stock<CODE> </CODE><CODE>:</CODE><CODE> </CODE>int;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>price<CODE> </CODE><CODE>:</CODE><CODE> </CODE>int<CODE> </CODE>}<CODE> </CODE>;;<BR>

</PRE>

</span><script language="JavaScript"><!--
  closePopUp("12_APPEND/PDcor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<!-- POPUP DEFINITION -->
<layer id="l__13_APPEND/PDcor.ml.tex" class="hint" visibility="hide" style="visibility:hidden; position:absolute" width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","13_APPEND/PDcor.ml.tex","");
// --></script><span style="">
 

<PRE><BR># <B>let</B><CODE> </CODE>array_index<CODE> </CODE>t<CODE> </CODE>f<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>i<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><CODE>0</CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Array.length<CODE> </CODE>t<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>while</B><CODE> </CODE><TT>(</TT><CODE>!</CODE>i<CODE> </CODE><CODE>&lt;</CODE><CODE> </CODE>n<TT>)</TT><CODE> </CODE><CODE>&amp;</CODE><CODE> </CODE><TT>(</TT>not<CODE> </CODE><TT>(</TT>f<CODE> </CODE>t<CODE>.</CODE><TT>(</TT><CODE>!</CODE>i<TT>)</TT><TT>)</TT><TT>)</TT><CODE> </CODE><B>do</B><CODE> </CODE>incr<CODE> </CODE>i<CODE> </CODE><B>done</B><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE><CODE>!</CODE>i<CODE>=</CODE>n<CODE> </CODE><B>then</B><CODE> </CODE>raise<CODE> </CODE>Not_found<CODE> </CODE><B>else</B><CODE> </CODE><CODE>!</CODE>i<CODE> </CODE>;;<BR><CODE>val array_index : 'a array -&gt; ('a -&gt; bool) -&gt; int = &lt;fun&gt;</CODE><BR>

</PRE>

</span><script language="JavaScript"><!--
  closePopUp("13_APPEND/PDcor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<script language="JavaScript"><!--
  initializePreviousHints();
// --></script><BR>
<BR>

<LI> Write the service function <TT><A id="a323__14_APPEND/PDcor.ml.tex" href="javascript: void showMessage('14_APPEND/PDcor.ml.tex')" class="mousable"><SPAN style=""><!-- 14,APPEND/PDcor.ml.tex,waiter -->waiter</SPAN></A></TT>. 
<!-- POPUP DEFINITION -->
<layer id="l__14_APPEND/PDcor.ml.tex" class="hint" visibility="hide" style="visibility:hidden; position:absolute" width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","14_APPEND/PDcor.ml.tex","");
// --></script><span style="">
 

<PRE><BR># <B>let</B><CODE> </CODE>waiter<CODE> </CODE>mach<CODE> </CODE>ic<CODE> </CODE>oc<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>f_in<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Unix.descr_of_in_channel<CODE> </CODE>ic<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>f_out<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Unix.descr_of_out_channel<CODE> </CODE>oc<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><B>try</B><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>send_answer<CODE> </CODE>f_out<CODE> </CODE><TT>(</TT>mach#get_menu()<TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>drink_name<CODE> </CODE><CODE>=</CODE><CODE> </CODE>get_request<CODE> </CODE>f_in<CODE> </CODE><B>in</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>num_drink<CODE> </CODE><CODE>=</CODE><CODE> </CODE>mach#get_drink_index<CODE> </CODE>drink_name<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>drink_price<CODE> </CODE><CODE>=</CODE><CODE> </CODE>mach#get_drink_price<CODE> </CODE>num_drink<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>send_answer<CODE> </CODE>f_out<CODE> </CODE><CODE>[</CODE>string_of_int<CODE> </CODE>drink_price<CODE>]</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>paid<CODE> </CODE><CODE>=</CODE><CODE> </CODE>int_of_string<CODE> </CODE><TT>(</TT>get_request<CODE> </CODE>f_in<TT>)</TT><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>paid<CODE> </CODE><CODE>&lt;</CODE><CODE> </CODE>drink_price<CODE> </CODE><B>then</B><CODE> </CODE>failwith<CODE>"NotEnough"</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>num_cmd<CODE> </CODE><CODE>=</CODE><CODE> </CODE>mach#set_cmd<CODE> </CODE>num_drink<CODE> </CODE>paid<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>drink_name<CODE>,</CODE><CODE> </CODE>change<CODE> </CODE><CODE>=</CODE><CODE> </CODE>mach#wait_cmd<CODE> </CODE>num_cmd<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>mach#deliver_drink<CODE> </CODE>num_drink;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>send_answer<CODE> </CODE>f_out<CODE> </CODE><CODE>[</CODE>drink_name;<CODE> </CODE><TT>(</TT>string_of_int<CODE> </CODE>change<TT>)</TT><CODE>]</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>with</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Not_found<CODE> </CODE>-&gt;<CODE> </CODE>send_cancel<CODE> </CODE>f_out<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Failure<TT>(</TT><CODE>"int_of_string"</CODE><TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE>send_cancel<CODE> </CODE>f_out<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Failure<TT>(</TT><CODE>"I/O error"</CODE><TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE>send_cancel<CODE> </CODE>f_out<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Failure<TT>(</TT><CODE>"NotEnough"</CODE><TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE>send_cancel<CODE> </CODE>f_out<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Failure<TT>(</TT><CODE>"BadRequestFormat"</CODE><TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE>send_cancel<CODE> </CODE>f_out<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>)</TT>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>close_in<CODE> </CODE>ic<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>flush<CODE> </CODE>oc<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>close_out<CODE> </CODE>oc<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Thread.exit<CODE> </CODE>()<CODE> </CODE>;;<BR><CODE>val waiter :</CODE><BR><CODE>  &lt; deliver_drink : 'a -&gt; 'b; get_drink_index : string -&gt; 'a;</CODE><BR><CODE>    get_drink_price : 'a -&gt; int; get_menu : unit -&gt; string list;</CODE><BR><CODE>    set_cmd : 'a -&gt; int -&gt; 'c; wait_cmd : 'c -&gt; string * int; .. &gt; -&gt;</CODE><BR><CODE>  in_channel -&gt; out_channel -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>

</span><script language="JavaScript"><!--
  closePopUp("14_APPEND/PDcor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<script language="JavaScript"><!--
  initializePreviousHints();
// --></script><BR>
<BR>

<LI> Write the principal function <TT><A id="a324__15_APPEND/PDcor.ml.tex" href="javascript: void showMessage('15_APPEND/PDcor.ml.tex')" class="mousable"><SPAN style=""><!-- 15,APPEND/PDcor.ml.tex,maincafed -->main</SPAN></A></TT> 
that obtains a port number for the service from the 
command line and performs a number of initialization tasks. 
In particular, the coffee machine executes in a 
process.
<!-- POPUP DEFINITION -->
<layer id="l__15_APPEND/PDcor.ml.tex" class="hint" visibility="hide" style="visibility:hidden; position:absolute" width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","15_APPEND/PDcor.ml.tex","");
// --></script><span style="">
 

<PRE><BR># <B>let</B><CODE> </CODE>main<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>Array.length<CODE> </CODE>Sys.argv<CODE> </CODE><CODE>&lt;</CODE><CODE> </CODE><CODE>2</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>then</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>begin</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Printf.eprintf<CODE> </CODE><CODE>"usage : %s port\n"</CODE><CODE> </CODE>Sys.argv<CODE>.</CODE><TT>(</TT><CODE>0</CODE><TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>exit<CODE> </CODE><CODE>1</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>end</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>begin</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>port<CODE> </CODE><CODE>=</CODE><CODE> </CODE>int_of_string<CODE> </CODE>Sys.argv<CODE>.</CODE><TT>(</TT><CODE>1</CODE><TT>)</TT><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>f_cmd<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>new</B><CODE> </CODE>cmd_fifo<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>t_ready<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>new</B><CODE> </CODE>ready_table<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>mach<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>new</B><CODE> </CODE>machine<CODE> </CODE>f_cmd<CODE> </CODE><TT>(</TT>t_ready<CODE> </CODE><CODE>1</CODE><CODE>3</CODE><TT>)</TT><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>ignore<CODE> </CODE><TT>(</TT>Thread.create<CODE> </CODE>mach#run<CODE> </CODE>()<TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>establish_server<CODE> </CODE><TT>(</TT>waiter<CODE> </CODE>mach<TT>)</TT><CODE> </CODE><TT>(</TT>Unix<CODE>.</CODE>ADDR_INET<CODE> </CODE><TT>(</TT>my_inet_addr<CODE> </CODE>()<CODE>,</CODE><CODE> </CODE>port<TT>)</TT><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>end</B><CODE> </CODE>;;<BR><CODE>val main : unit -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>

</span><script language="JavaScript"><!--
  closePopUp("15_APPEND/PDcor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<script language="JavaScript"><!--
  initializePreviousHints();
// --></script></OL><HR>
<A HREF="book-ora188.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora190.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
